package cn.liangent.travlib.util;

import cn.liangent.travlib.*;
import HTTPClient.*;
import java.util.*;
import java.util.regex.*;

public class Utilities {
	private Utilities() {}
	
	/**
	 * This equals find(source, regex, "$1")
	 */
	public static String find(String source, String regex) throws BadPageException {
		return find(source, regex, "$1");
	}
	
	/**
	 * This equals <code>find(source, regex, "$" + target)</code>
	 * If target < 0, IllegalArgumentException will be thrown
	 * (target == 0 means the whole regex-matched substring)
	 */
	public static String find(String source, String regex, int target) throws BadPageException {
		if (target < 0) {
			throw new IllegalArgumentException("target < 0");
		}
		return find(source, regex, "$" + target);
	}
	
	/**
	 * <code>find("abcde123fghijkl456mnabcde789fgh", "de(\\d{3})fg", "$1") == "123"</code>
	 * If nothing can be found, or no Groups, returns null.
	 */
	public static String find(String source, String regex, String target) throws BadPageException {
		String retv = findNoThrow(source, regex, target);
		if (retv == null) throw new BadPageException(regex + " not found");
		return retv;
	}
	
	public static String findNoThrow(String source, String regex) throws BadPageException {
		return findNoThrow(source, regex, "$1");
	}
	
	public static String findNoThrow(String source, String regex, int target) throws BadPageException {
		if (target < 0) {
			throw new IllegalArgumentException("target < 0");
		}
		return findNoThrow(source, regex, "$" + target);
	}
	
	public static String findNoThrow(String source, String regex, String target) {
		Matcher mc = Pattern.compile(regex).matcher(source);
		// groupCount() checking has been removed because $0 can be required
		if (!mc.find()) return null;
		return mc.group().replaceAll(regex, target);
	}
	
	public static NVPair findNVPair(String source, String regex) throws BadPageException {
		return findNVPair(source, regex, "$1", "$2");
	}
	
	public static NVPair findNVPair(String source, String regex, int ntarget, int vtarget) throws BadPageException {
		if (ntarget < 0 || vtarget < 0) {
			throw new IllegalArgumentException("ntarget < 0 || vtarget < 0");
		}
		return findNVPair(source, regex, "$" + ntarget, "$" + vtarget);
	}
	
	public static NVPair findNVPair(String source, String regex, String ntarget, String vtarget) throws BadPageException {
		Matcher mc = Pattern.compile(regex).matcher(source);
		// groupCount() checking has been removed because $0 can be required
		if (!mc.find()) throw new BadPageException(regex + " not found");
		String fd = mc.group();
		return new NVPair(fd.replaceAll(regex, ntarget), fd.replaceAll(regex, vtarget));
	}

	public static String[] findAll(String source, String regex) throws BadPageException {
		return findAll(source, regex, "$1");
	}

	public static String[] findAll(String source, String regex, int target) throws BadPageException {
		if (target < 0) {
			throw new IllegalArgumentException("target < 0");
		}
		return findAll(source, regex, "$" + target);
	}
	
	@SuppressWarnings("unchecked")
	public static String[] findAll(String source, String regex, String target) throws BadPageException {
		ArrayList<String> al = new ArrayList<String>();
		Matcher mc = Pattern.compile(regex).matcher(source);
		// groupCount() checking has been removed because $0 can be required
		if (!mc.find()) return null;
		al.add(mc.group().replaceAll(regex, target));
		while (mc.find()) {
			al.add(mc.group().replaceAll(regex, target));
		}
		return (String[])(al.toArray()); // if i dont want a new array... just which is in ArrayList?
	}
	
	public static String removeLineSeparator(String str) {
		return changeLineSeparator(str, "");
	}

	/**
	 * target is not regex, null to remove line separator (equals "")
	 */
	public static String changeLineSeparator(String str, String target) {
		if (str == null) {
			return str;
		}
		if (target == null) {
			target = "";
		}
		boolean ateCR = false;
		StringBuilder sb = new StringBuilder();
		for (char ch : str.toCharArray()) {
			if (ateCR) {
				switch (ch) {
				case '\r':
					sb.append(target);
					break;
				case '\n':
					sb.append(target);
					ateCR = false;
					break;
				default:
					sb.append(target).append(ch);
					ateCR = false;
				}
			} else {
				switch (ch) {
				case '\r':
					ateCR = true;
					break;
				case '\n':
					sb.append(target);
					break;
				default:
					sb.append(ch);
				}
			}
		}
		if (ateCR) {
			sb.append(target);
		}
		return sb.toString();
	}
	
	public static boolean haveToLogin(String source) {
		return source.contains("<input type=\"image\" value=\"login\" border=\"0\" name=\"s1\"");
	}
	
	// more accurate Exception?
	public static void checkResourceBundle(ResourceBundle bundle) throws MissingResourceException {
	}
}
